import { Connection, Channel } from 'amqplib';

// Extended types for better type safety
export interface ExtendedConnection extends Connection {
  connection?: {
    destroyed?: boolean;
  };
}

// Type for channels with additional methods
export type ExtendedChannel = Channel & {
  // Add methods that might not be in the base Channel type
  confirmSelect?(): Promise<void>;
  txSelect?(): Promise<void>;
  txCommit?(): Promise<void>;
  txRollback?(): Promise<void>;
  publish?(
    exchange: string,
    routingKey: string,
    content: Buffer,
    options?: PublishOptions,
    callback?: (error: Error | null, ok?: boolean) => void
  ): boolean;
  sendToQueue?(
    queue: string,
    content: Buffer,
    options?: PublishOptions,
    callback?: (error: Error | null, ok?: boolean) => void
  ): boolean;
};

// Connection options with proper typing
export interface ConnectionOptions {
  heartbeat?: number;
  timeout?: number;
  protocol?: 'amqp' | 'amqps';
  ssl?: Record<string, unknown>;
  [key: string]: unknown;
}

// Publish options with proper typing
export interface PublishOptions {
  expiration?: string;
  userId?: string;
  CC?: string | string[];
  mandatory?: boolean;
  persistent?: boolean;
  deliveryMode?: number;
  BCC?: string | string[];
  immediate?: boolean;
  contentType?: string;
  contentEncoding?: string;
  headers?: Record<string, string | number | boolean>;
  priority?: number;
  correlationId?: string;
  replyTo?: string;
  messageId?: string;
  timestamp?: number;
  type?: string;
  appId?: string;
  [key: string]: unknown;
}

// 基础类型定义
export interface RabbitMQConfig {
  host: string;
  port: number;
  username: string;
  password: string;
  virtualHost: string;
  heartbeat?: number;
  connectionTimeout?: number;
  sslEnabled?: boolean;
  sslOptions?: Record<string, unknown>;
  maxRetries?: number;
  retryDelay?: number;
}

export interface MessageHeaders {
  [key: string]: string | number | boolean | undefined;
}

export interface MessageProperties {
  [key: string]: unknown;
}

export interface MessageData {
  id: string;
  body: unknown;
  headers: MessageHeaders;
  properties: MessageProperties;
  timestamp: number;
  retryCount: number;
}

// Type guard for MessageData
export function isMessageData(data: unknown): data is MessageData {
  return (
    typeof data === 'object' &&
    data !== null &&
    typeof (data as MessageData).id === 'string' &&
    typeof (data as MessageData).timestamp === 'number' &&
    typeof (data as MessageData).retryCount === 'number' &&
    typeof (data as MessageData).headers === 'object' &&
    typeof (data as MessageData).properties === 'object'
  );
}

export interface ProcessResult {
  success: boolean;
  message?: string;
  data?: unknown;
  shouldRetry: boolean;
}

// 交换机和队列配置
export enum ExchangeType {
  DIRECT = 'direct',
  TOPIC = 'topic',
  FANOUT = 'fanout',
  HEADERS = 'headers',
}

export interface ExchangeConfig {
  name: string;
  type: ExchangeType;
  durable: boolean;
  autoDelete: boolean;
  arguments?: Record<string, unknown>;
}

export interface QueueConfig {
  name: string;
  durable: boolean;
  exclusive: boolean;
  autoDelete: boolean;
  arguments?: Record<string, unknown>;
}

export interface BindingConfig {
  queueName: string;
  exchangeName: string;
  routingKey: string;
  arguments?: Record<string, unknown>;
}

// 连接池相关
export interface ConnectionPoolConfig {
  poolSize: number;
  acquireTimeout: number;
  idleTimeout: number;
  reapInterval: number;
  // 动态扩展配置
  minPoolSize?: number;
  maxPoolSize?: number;
  dynamicScaling?: boolean;
  scaleUpThreshold?: number;  // 当等待连接的请求数超过此值时扩展
  scaleDownThreshold?: number; // 当空闲连接数超过此值时收缩
  scaleUpStep?: number;       // 每次扩展的连接数
  scaleDownStep?: number;     // 每次收缩的连接数
}

export interface ManagedConnection {
  connection: ExtendedConnection;
  channel: ExtendedChannel;
  isActive: boolean;
  lastUsed: number;
}

// 中间件相关
export interface MiddlewareContext {
  message: MessageData;
  metadata: Record<string, unknown>;
}

// 序列化器接口
export interface MessageSerializer {
  serialize(data: unknown): string;
  deserialize(data: string): unknown;
}

// 处理器接口
export interface MessageHandler {
  handle(message: MessageData): Promise<ProcessResult>;
  onError?(message: MessageData, error: Error): Promise<ProcessResult>;
  shouldRetry?(message: MessageData, error: Error): boolean;
}

// 生产者和消费者接口
export interface ProducerOptions {
  exchange?: string;
  routingKey?: string;
  persistent?: boolean;
  priority?: number;
  expiration?: number;
  headers?: MessageHeaders;
}

export interface ConsumerOptions {
  queueName: string;
  autoAck?: boolean;
  prefetchCount?: number;
  exclusive?: boolean;
  consumerTag?: string;
  arguments?: Record<string, unknown>;
}

// 性能监控相关
export interface MessageMetrics {
  sentCount: number;
  receivedCount: number;
  processedCount: number;
  failedCount: number;
  retryCount: number;
  averageProcessingTime: number;
  lastUpdated: number;
}

export interface PerformanceTestResult {
  messageCount: number;
  duration: number;
  throughput: number;
  concurrentProducers: number;
  latencyStats?: {
    min: number;
    max: number;
    avg: number;
    p95: number;
    p99: number;
  };
}

// 企业级功能相关
export interface TenantConfig {
  tenantId: string;
  virtualHost: string;
  queuePrefix: string;
  exchangePrefix: string;
  resourceLimits: {
    maxConnections?: number;
    maxQueues?: number;
    maxExchanges?: number;
  };
}

export interface TracingContext {
  traceId: string;
  spanId: string;
  parentSpanId?: string;
  baggage?: Record<string, string>;
}

export interface MessageVersion {
  version: string;
  schemaClass: new () => unknown;
}

// 错误类型
export class RabbitMQError extends Error {
  constructor(
    message: string,
    public readonly code?: string,
    public readonly shouldRetry: boolean = false
  ) {
    super(message);
    this.name = 'RabbitMQError';
  }
}

export class ConnectionError extends RabbitMQError {
  constructor(message: string, shouldRetry = true) {
    super(message, 'CONNECTION_ERROR', shouldRetry);
    this.name = 'ConnectionError';
  }
}

export class MessageError extends RabbitMQError {
  constructor(message: string, shouldRetry = false) {
    super(message, 'MESSAGE_ERROR', shouldRetry);
    this.name = 'MessageError';
  }
}

export class ValidationError extends RabbitMQError {
  constructor(message: string) {
    super(message, 'VALIDATION_ERROR', false);
    this.name = 'ValidationError';
  }
}

// 工具类型
export type AsyncFunction<T = unknown> = (...args: unknown[]) => Promise<T>;
export type SyncFunction<T = unknown> = (...args: unknown[]) => T;

// RPC method types
export type RPCMethod = (...args: any[]) => Promise<unknown> | unknown;
export type RPCMethodRegistry = Record<string, RPCMethod>;

export interface Logger {
  debug(message: string, meta?: Record<string, unknown>): void;
  info(message: string, meta?: Record<string, unknown>): void;
  warn(message: string, meta?: Record<string, unknown>): void;
  error(message: string, error?: Error, meta?: Record<string, unknown>): void;
}

// 事件类型
export interface RabbitMQEvents {
  connected: () => void;
  disconnected: (error?: Error) => void;
  error: (error: Error) => void;
  messageReceived: (message: MessageData) => void;
  messageProcessed: (message: MessageData, result: ProcessResult) => void;
  messageFailed: (message: MessageData, error: Error) => void;
}

export type EventListener<T extends keyof RabbitMQEvents> = RabbitMQEvents[T];
